﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Infrastructure.ObjectModel;
using Infrastructure.Managers;
using B10_Ex02_EladLebovitch_034695114.Interfaces;
using Infrastructure.ServiceInterfaces;

namespace B10_Ex02_EladLebovitch_034695114.ObjectModel
{
    public class Barrier : Sprite, ICollidable2D, IPlayerObjects
    {
        private const int k_TextureWidth = 44;
        private const int k_TextureHeigth = 32;

        public int Index
        {
            get;
            set;
        }

        public ContentManager Content
        {
            get;
            set;
        }

        /// <summary>
        /// Constructs a Barrier sprite
        /// </summary>
        /// <param name="i_game">The game</param>
        /// <param name="i_assetName">The texture</param>
        public Barrier(Game i_game, string i_assetName, int i_barrierIndex, ContentManager i_content)
            : base(i_assetName, i_game)
        {
            Index = i_barrierIndex;
            this.SourceRectangle = new Rectangle(i_barrierIndex * k_TextureWidth, 0, k_TextureWidth, 32);
            this.Content = i_content; 
        }

        protected override void InitBounds()
        {
            this.m_WidthBeforeScale = this.SourceRectangle.Width;
            this.m_HeightBeforeScale = this.SourceRectangle.Height;
            this.PositionOrigin = new Vector2(this.SourceRectangle.Width / 2, this.SourceRectangle.Height / 2);
            this.RotationOrigin = new Vector2(this.SourceRectangle.Width / 2, this.SourceRectangle.Height / 2);
        }

        protected override void LoadContent()
        {
            base.LoadContent();
            this.Texture = Content.Load<Texture2D>("Content\\" + AssetName);
        }

        public event ColidedEventHandler ColidedAndChanged;
        protected virtual void OnColidedAndChanged()
        {
            if (ColidedAndChanged != null)
            {
                ColidedAndChanged(this);
            }
        }

        public override void Collided(ICollidable i_Collidable)
        {
            Vector2 BulletDestroySize = new Vector2(6, 12);
            ICollidable2D source = i_Collidable as ICollidable2D;

            // If it's an enemy bullet
            if (i_Collidable is IEnemyObjects && (i_Collidable is IHarmful))
            {
                eatMeAt(new Rectangle(source.Bounds.Left,
                    source.Bounds.Top + (int)BulletDestroySize.Y, 
                    (int)BulletDestroySize.X, 
                    (int)BulletDestroySize.Y));                    
            }
            // If it's an enemy bullet
            else if (i_Collidable is IPlayerObjects && (i_Collidable is IHarmful))
            {
                eatMeAt(new Rectangle(source.Bounds.Left,
                    source.Bounds.Top - (int)BulletDestroySize.Y,
                    (int)BulletDestroySize.X,
                    source.Bounds.Top));
            }
            // If it's an enemy sprite
            else if (i_Collidable is IEnemyObjects)
            {
                eatMeAt(source.Bounds);
            }

            (Game.Services.GetService(typeof(ISoundManeger)) as ISoundManeger).PlayCue("BarrierHit");
        }

        private void eatMeAt(Rectangle i_TargetRect)
        {
            Rectangle i_rectangleA = new Rectangle(0, 0, Texture.Width, Texture.Height);
            Rectangle i_rectangleB = SourceRectangle;

            // Find the bounds of the rectangle intersection
            int top = Math.Max(i_rectangleA.Top, i_rectangleB.Top);
            int bottom = Math.Min(i_rectangleA.Bottom, i_rectangleB.Bottom);
            int left = Math.Max(i_rectangleA.Left, i_rectangleB.Left);
            int right = Math.Min(i_rectangleA.Right, i_rectangleB.Right);

            // Find the bounds of the rectangle intersection
            int topR = Math.Max(this.Bounds.Top, i_TargetRect.Top) - this.Bounds.Top;
            int bottomR = Math.Min(this.Bounds.Bottom, i_TargetRect.Bottom) - this.Bounds.Top;
            int leftR = Math.Max(this.Bounds.Left, i_TargetRect.Left) - this.Bounds.Left;
            int rightR = Math.Min(this.Bounds.Right, i_TargetRect.Right) - this.Bounds.Left;

            // Check every point within the intersection bounds
            for (int y = top; y < bottom; y++)
            {
                for (int x = left; x < right; x++)
                {
                    int normX = x - left;
                    int normY = y - top;
                    if ((normY >= topR && normY < bottomR) &&
                        (normX >= leftR && normX < rightR))
                    {
                        // Set the color of both pixels at this point
                        m_TextureData[(x - i_rectangleA.Left) + (y - i_rectangleA.Top) * i_rectangleA.Width] =
                            Color.TransparentWhite;
                    }
                }
            }

            Texture.SetData <Color>(m_TextureData);
            updateSourceRectTexture();
            OnColidedAndChanged();
        }            
    }
}
